#ifndef __MY_UTIL__
#define __MY_UTIL__

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <memory>
#include <unistd.h>
#include <sys/stat.h>
#include <jsoncpp/json/json.h>

#endif

namespace ctv{
    class FileUtil{
        private:
            std::string _name;
        public:
            FileUtil(const std::string name)
                :_name(name){}
            bool Exists()//判断文件是否存在
            {
                //F_OK用来判断文件是否存在,存在则返回0
                int ret = access(_name.c_str(), F_OK);
                if(ret != 0)
                {
                    std::cout << "file is not exists\n";
                    return false;
                }
                return true;
            }
            size_t Size()//获取文件大小
            {
                if(this->Exists() == false)
                {
                    return 0;
                }

                struct stat st;
                //stat获取文件属性,st_size就是文件大小
                int ret = stat(_name.c_str(), &st);
                if(ret != 0)
                {
                    std::cout << "get file stat failed!\n";
                    return 0;
                }
                return st.st_size;
            }
            bool GetContent(std::string *body)//读取数据到body中
            {
                std::ifstream ifs;
                ifs.open(_name, std::ios::binary);
                if(ifs.is_open() == false)
                {
                    std::cout << "open file failed\n";
                    return false;
                }

                size_t flen = this->Size();
                body->reserve(flen);


                ifs.read(&(*body)[0], flen);
                if(ifs.good() == false)
                {
                    std::cout << "read fail content failed!\n";
                    ifs.close();
                    return false;
                }

                ifs.close();
                //调试
                std::cout << "输出" << std::endl;
                return true;
            }
            bool SetContent(const std::string &body)//向文件中写入数据
            {
                std::ofstream ofs;
                ofs.open(_name, std::ios::binary);
                if(ofs.is_open() == false)
                {
                    std::cout << "open file failed\n";
                    return false;
                }

                ofs.write(body.c_str(), body.size());
                if(ofs.good() == false)
                {
                    std::cout << "write fail content failed!\n";
                    ofs.close();
                    return false;
                }

                ofs.close();
                return true;
            }
            bool CreateDiretory()//针对目录创建目录
            {
                if(this->Exists())
                {
                    return true;
                }

                mkdir(_name.c_str(), 0777);
                return true;
            }
    };

    class JsonUtil{
        public:
            //静态函数没有this指针，直接通过类名使用
            static bool Serialize(const Json::Value &value, std::string *body)
            {
                Json::StreamWriterBuilder swb;
                std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());

                std::stringstream ss;
                int ret = sw->write(value, &ss);
                if(ret != 0)
                {
                    std::cout << "Serilaize failed!\n";
                    return false;
                }
                *body = ss.str();
                return true;
            }

            static bool UnSerialize(const std::string &body, Json::Value *value)
            {
                Json::CharReaderBuilder crb;
                std::unique_ptr<Json::CharReader> cr(crb.newCharReader());

                std::string err;
                bool ret = cr->parse(body.c_str(), body.c_str() + body.size(), value, &err);
                if(ret == false)
                {
                    std::cout << "UnSerialize failed!\n";
                    return false;
                }
                return true;
            }

    };
}
